﻿

using System.Collections.Generic;
using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using AutoNyaa.Logic;
using System.Threading;
using AutoNyaa.Logic.Entities;
using System.Configuration;
using MonoTorrent.Client;
using System.Text;
using System.ComponentModel;
namespace AutoNyaa
{
    public partial class MainForm : Form
    {
        #region Fields

        private string _filter = "^.*$";
        private char[] _delimiters = new char[] { ' ', '_', '.' };

        private Thread _filterThread;
        private FilterManager _filterManager;

        private Thread _downloadThread;
        private DownloadManager _downloadManager;

        private Thread _torrentThread;
        private TorrentManagerWrapper _torrentManager;

        private BindingList<TorrentManager> _torrents;

        private bool _exit = false;

        private string _delimiterRegex
        {
            get
            {
                string returnString = "";

                foreach (char delimiter in _delimiters)
                {
                    returnString += delimiter.ToString();
                }

                return "[" + returnString + "]";
            }
        }

        private System.Threading.Timer _uiUpdateTimer;

        #endregion

        #region Constructors

        public MainForm()
        {
            InitializeComponent();

            Initialize();

            _filterManager = new FilterManager();
            _downloadManager = new DownloadManager();
            _torrentManager = new TorrentManagerWrapper();

            _filterThread = new Thread(new ThreadStart(_filterManager.Run));
            _filterThread.IsBackground = true;
            _filterThread.Start();

            _downloadThread = new Thread(new ThreadStart(_downloadManager.Run));
            _downloadThread.IsBackground = true;
            _downloadThread.Start();

            _torrentThread = new Thread(new ThreadStart(_torrentManager.Run));
            _torrentThread.IsBackground = true;
            _torrentThread.Start();

            _filterManager.FiltersUpdated += this.FiltersUpdated;
            _filterManager.DownloadItemDetected += this.DownloadItemDetected;
            _downloadManager.TorrentDownloadCompleted += this.TorrentDownloadCompleted;

            _uiUpdateTimer = new System.Threading.Timer(new TimerCallback(UpdateUI), null, 1000, 1000);

            _torrents = _torrentManager.TorrentManagerList;

            dataGridViewTorrents.AutoGenerateColumns = true;
            dataGridViewTorrents.DataSource = _torrents;


                 }

        private void Initialize()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            
            comboBoxCategory.DisplayMember = "Description";
            comboBoxFilter.DisplayMember = "Description";
            listBoxFilter.DisplayMember = "Title";

            comboBoxCategory.Items.Add(new ListItem() { Description = "All", Value = "0_0" });
            comboBoxCategory.Items.Add(new ListItem() { Description = "Anime", Value = "1_0" });
            comboBoxCategory.Items.Add(new ListItem() { Description = "Anime Music Video", Value = "1_32" });
            comboBoxCategory.Items.Add(new ListItem() { Description = "English Translated Anime", Value = "1_37" });
            comboBoxCategory.Items.Add(new ListItem() { Description = "Non-English Translated Anime", Value = "1_38" });
            comboBoxCategory.Items.Add(new ListItem() { Description = "Raw Anime", Value = "1_11" });

            comboBoxFilter.Items.Add(new ListItem() { Description = "All", Value = "0" });
            comboBoxFilter.Items.Add(new ListItem() { Description = "Filter Remakes", Value = "1" });
            comboBoxFilter.Items.Add(new ListItem() { Description = "Trusted Only", Value = "2" });
            comboBoxFilter.Items.Add(new ListItem() { Description = "A+ Only", Value = "3" });

            comboBoxCategory.SelectedIndex = 0;
            comboBoxFilter.SelectedIndex = 0;
        }

        #endregion

        #region Events

        private void button1_Click(object sender, EventArgs e)
        {
            RssFeed feed = RssFeed.Deserialize(new Uri(ConfigurationManager.AppSettings["NyaaUrl"]), 1, textBoxSearch.Text, ((ListItem)comboBoxCategory.SelectedItem).Value, ((ListItem)comboBoxFilter.SelectedItem).Value);

            listViewResults.Items.Clear();

            foreach (Item item in feed.Items)
            {
                listViewResults.Items.Add(new ListViewItem(new string[] { item.Title, item.Category, item.PublishDate.ToString() }));

            }
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (listViewResults.SelectedItems.Count > 1)
            {
                List<string> words = new List<string>();


                foreach (ListViewItem selectedItem in listViewResults.SelectedItems)
                {
                    string[] wordsString = selectedItem.Text.Split(_delimiters);
                    for (int i = 0; i < wordsString.Length; i++)
                    {
                        if (words.Count <= i)
                        {
                            words.Add(Regex.Escape(wordsString[i]));
                        }
                        else
                        {
                            if (words[i] != Regex.Escape(wordsString[i]))
                            {
                                words[i] = ".*";
                            }
                        }

                    }
                }
                _filter = "^";
                foreach (string word in words)
                {
                    _filter += word + _delimiterRegex;
                }
                _filter = _filter.Substring(0, (_filter.Length - _delimiterRegex.Length));
                _filter += "$";

                PopulateFilter();
            }


        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            Filter filter = new Filter()
            {
                Category = (ListItem)comboBoxCategory.SelectedItem,
                TypeFilter = (ListItem)comboBoxFilter.SelectedItem,
                FilterRegex = textBoxFilterResult.Text,
                LastUpdated = DateTime.Now,
                SearchString = textBoxSearchResult.Text
            };
            _filterManager.AddFilter(filter);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }
        }

        private void toolStripMenuItemOpen_Click(object sender, EventArgs e)
        {
            this.Show();
        }

        private void toolStripMenuItemExit_Click(object sender, EventArgs e)
        {
            _exit = true;

            _filterManager.Exit();
            _downloadManager.Exit();
            _torrentManager.Exit();

            _filterThread.Join();
            _downloadThread.Join();
            _torrentThread.Join();

            Application.Exit();
        }

        #endregion

        #region Methods

        public void PopulateFilter()
        {
            textBoxSearchResult.Text = textBoxSearch.Text;
            textBoxFilterResult.Text = _filter;
            RssFeed feed = RssFeed.Deserialize(new Uri(ConfigurationManager.AppSettings["NyaaUrl"]), 1, textBoxSearch.Text, ((ListItem)comboBoxCategory.SelectedItem).Value, ((ListItem)comboBoxFilter.SelectedItem).Value);

            listBoxFilter.Items.Clear();

            RegexStringValidator validator = new RegexStringValidator(_filter);

            foreach (Item item in feed.Items)
            {
                try
                {
                    // Attempt validation.
                    validator.Validate(item.Title);
                    listBoxFilter.Items.Add(item);
                }
                catch (ArgumentException)
                {
                    continue;
                }
            }
        }

        private void FiltersUpdated()
        {
            PopulateFilters();
        }

        private void DownloadItemDetected(Item item)
        {
            _downloadManager.StartDownload(item.Link, Properties.UserSettings.Default.TorrentFolder + item.Title);
        }

        private void TorrentDownloadCompleted(Download download)
        {
            _torrentManager.StartTorrent(download.Location, Properties.UserSettings.Default.DownloadFolder);
        }

        private void PopulateFilters()
        {
            listViewAllFilters.Clear();

            foreach (Filter filter in _filterManager.Filters)
            {
                listViewAllFilters.Items.Add(new ListViewItem(filter.SearchString + " | " + filter.FilterRegex));
            }
        }

        private void UpdateUI(object state)
        {
            this.BeginInvoke(new MethodInvoker(UpdateUI));
        }
        
        private void UpdateUI()
        {
            _torrents = _torrentManager.TorrentManagerList;
            dataGridViewTorrents.Refresh();
      //     listViewTorrents.BeginUpdate();

      //    // SuspendLayout();

      ////     listViewTorrents.Items.Clear();



      //     foreach (TorrentManager torrent in torrents)
      //     {
      //         ListViewItem[] items = listViewTorrents.Items.Find(InfoHashToString(torrent.Torrent.InfoHash), false);

      //         ListViewItem item;

      //         if (items.Length == 0 || items[0] == null)
      //         {
      //             double size = Math.Round((double)torrent.FileManager.FileSize / 1024 / 1024, 2);

      //             item = new ListViewItem(torrent.Torrent.Name);
      //             item.Name = InfoHashToString(torrent.Torrent.InfoHash);

      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, torrent.FileManager.Files[0].ToString()));
      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, size + " mb"));
      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, ""));
      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, ""));
      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, ""));
      //             item.SubItems.Add(new ListViewItem.ListViewSubItem(item, ""));

      //             listViewTorrents.Items.Add(item);
      //         }
      //         else
      //         {
      //             item = items[0];
      //         }

      //         double percentageDownloaded = Math.Round(100.0 / torrent.FileManager.FileSize * torrent.Monitor.DataBytesDownloaded, 1);
               
      //         double dataDownloaded = Math.Round((double)torrent.Monitor.DataBytesDownloaded / 1024 / 1024, 2);

      //         item.SubItems[2].Text = dataDownloaded + " mb";
      //         item.SubItems[3].Text = percentageDownloaded + "%";
      //         item.SubItems[4].Text = torrent.Peers.Seeds.ToString();
      //         item.SubItems[5].Text = torrent.Peers.Leechs.ToString();
      //     }

      //      listViewTorrents.EndUpdate();

      //      //ResumeLayout(false);

            //PerformLayout();
        }

        #endregion

        private string InfoHashToString(byte[] hash)
        {
            string returnString = "";
            foreach (byte b in hash)
            {
                returnString += b.ToString();
            }
            return returnString;
        }
    }
}